package com.dzx.design.creational.prototype.clone;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Date;

/**
 * @author dzx
 * @ClassName:
 * @Description: 原型模式
 * @date 2019年07月30日 10:59:57
 */
public class Test {


    public static void main(String[] args) throws CloneNotSupportedException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Date date = new Date(0);
        Pig pig = new Pig("佩奇", date);
        Pig clone = (Pig) pig.clone();
        System.out.println(pig);
        System.out.println(clone);

        //默认为浅克隆，当我们修改pig对象的生日时候，clone对象的生日也跟着被修改了
        //如果要做到深克隆，就需要重写深克隆，并且在克隆的时候，需要克隆pig类里面属性为引用数据类型的对象
        //否则很容易引起bug
        pig.getBirthday().setTime(66666666L);
        System.out.println(pig);
        System.out.println(clone);

        //利用反射和克隆破坏单例模式
        SingletonExample4 instance = SingletonExample4.getInstance();

        Method clone1 = instance.getClass().getDeclaredMethod("clone");
        clone1.setAccessible(true);//原本是protected，需要打开访问权限
        //执行clone方法
        SingletonExample4 invoke = (SingletonExample4) clone1.invoke(instance);
        //发现instance 和 invoke 两个对象的引用地址是不同的，说明单例已被破坏掉
        //解决防范：1 不实现cloneable接口  2在重写的clone()方法中调用getInstance()方法
        System.out.println(instance);
        System.out.println(invoke);


    }
}
